use super::*;

/// 将要导出为xlsx文件的数据结构
struct MySimpleData {
    pub name: String,
    pub tel: String,
    pub dep: String,
}

impl MySimpleData {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }
}
// 实现trait，以便快捷导出为xlsx
impl XlsxGroupWrite for MySimpleData {
    /// 每行数据写入方式为简便模式
    /// 即直接根据line_writer_simple返回的对照表自动写入数据
    /// 无需了解xlsx写入api
    const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Simple;
    type ExtraArgType = ();
    /// 每一行写入四列数据，分别为：序号、姓名，手机和部门.
    /// # 参数说明
    ///
    /// * line_index 为正在写入行的行号，行号从1开始计数。
    fn line_writer_simple(&self, line_index: u32) -> Vec<XlsxColValue> {
        vec![
            // 因为第一行是自动生成的表头，因此序号-1
            XlsxColValue::new(line_index - 1, XlsxColValueType::NumberValue),
            XlsxColValue::new(&self.name, XlsxColValueType::StringValue),
            XlsxColValue::new(&self.tel, XlsxColValueType::StringValue),
            XlsxColValue::new(&self.dep, XlsxColValueType::StringValue),
        ]
    }
    /// 设置分组id
    ///
    /// 按照部门对数据进行分组
    /// 如网金部，写入到网金部文件，运管部写入到运管部文件中。
    fn group_make(&self) -> &str {
        &self.dep
    }
    /// 设置表头内容
    /// 列之间使用英文,分隔，将自动写入表格第一行。
    ///
    /// 设置四列表头分别为：序号、姓名、手机和部门。
    fn get_template() -> XlsxInitTemplet {
        XlsxInitTemplet::new_header("序号,姓名,手机,部门")
    }

    /// 输出xlsx文件名设置
    /// 生成的文件名称为：/tmp/test-分组id.xlsx
    const OUTPUT_FILE_NAME_GETTER_SIMPLE: Option<OutputFileNameSimpleGetter> =
        Some(OutputFileNameSimpleGetter::new(
            "/tmp/test",
            #[cfg(feature = "date")]
            false,
        ));
}

#[test]
fn test_simple_temp() {
    // 初始化待导出数据
    let data = vec![
        MySimpleData::new("张三", "185xxxx2228", "网金部"),
        MySimpleData::new("李四", "185xxxx2229", "运管部"),
        MySimpleData::new("王二", "185xxxx2230", "网金部"),
    ];
    // 导出数据到xlsx文件
    // 自动按照部门分别导出,同时还汇总导出一个汇总xlsx文件
    // 成功导出返回对应的文件信息和分组id
    #[cfg(feature = "encrypt")]
    let resp = MySimpleData::write2xlsx_all(&data, Some("abc95599"));
    #[cfg(not(feature = "encrypt"))]
    let resp = MySimpleData::write2xlsx_all(&data);
    /*

    Ok(
        [
            XlsxGroupWriteResp {
                group_id: "网金部",
                file_name: "/tmp/test-网金部.xlsx",
            },
            XlsxGroupWriteResp {
                group_id: "运管部",
                file_name: "/tmp/test-运管部.xlsx",
            },
            XlsxGroupWriteResp {
                group_id: "合并",
                file_name: "/tmp/test-合并.xlsx",
            },
        ],
    )
     */
    println!("{resp:#?}");
}

struct MyData {
    pub name: String,
    pub tel: String,
    pub dep: String,
}

impl MyData {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }
}

impl XlsxGroupWrite for MyData {
    const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Simple;
    type ExtraArgType = ();
    fn line_writer_simple(&self, line_index: u32) -> Vec<XlsxColValue> {
        vec![
            XlsxColValue::new(line_index - 3, XlsxColValueType::NumberValue),
            XlsxColValue::new(&self.name, XlsxColValueType::StringValue),
            XlsxColValue::new(&self.tel, XlsxColValueType::StringValue),
            XlsxColValue::new(&self.dep, XlsxColValueType::StringValue),
        ]
    }

    fn group_make(&self) -> &str {
        &self.dep
    }
    /// 设置以/home/feiy/Desktop/temp.xlsx为模板创建导出xlsx文件，
    /// 该模板中从第4行开始写入实际需要导出的数据。
    fn get_template() -> XlsxInitTemplet {
        XlsxInitTemplet::new_advance("/home/feiy/Desktop/temp.xlsx", 4)
    }
    /// 对生成的excel表格增加个性化信息
    ///
    /// 在第二行加入，部门信息和导出日期信息
    ///
    /// # 参数说明
    ///
    /// * sheet 要修改的xlsx工作表
    /// * group_id 该xlsx对应的分组id
    fn add_custom_info_to_sheet(sheet: &mut Worksheet, group_id: &str) {
        sheet
            .get_cell_mut((&1, &2))
            .set_value_string(&format!("{group_id}，报表日期:2023年4月20日"));
    }

    const OUTPUT_FILE_NAME_GETTER_SIMPLE: Option<OutputFileNameSimpleGetter> =
        Some(OutputFileNameSimpleGetter::new(
            "/tmp/test",
            #[cfg(feature = "date")]
            true,
        ));
}

#[test]
fn test_custom_info() {
    let data = vec![
        MyData::new("张三", "185xxxx2228", "网金部"),
        MyData::new("李四", "185xxxx2229", "运管部"),
        MyData::new("王二", "185xxxx2230", "网金部"),
    ];
    // 只分组导出对应部门xlsx文件，不导出所有数据合并到一个文件的汇总文件
    let resp = MyData::write2xlsx_group_only(
        &data,
        #[cfg(feature = "encrypt")]
        Some("abc95599"),
    );
    println!("{resp:#?}");
}

struct MyData2 {
    pub name: String,
    pub tel: String,
    pub dep: String,
}

impl MyData2 {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }
}

impl XlsxGroupWrite for MyData2 {
    const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Simple;
    type ExtraArgType = ();
    fn line_writer_simple(&self, line_index: u32) -> Vec<XlsxColValue> {
        vec![
            XlsxColValue::new(line_index - 2, XlsxColValueType::NumberValue),
            XlsxColValue::new(&self.name, XlsxColValueType::StringValue),
            XlsxColValue::new(&self.tel, XlsxColValueType::StringValue),
            XlsxColValue::new(&self.dep, XlsxColValueType::StringValue),
        ]
    }
    fn get_template() -> XlsxInitTemplet {
        XlsxInitTemplet::new_advance("/home/feiy/Desktop/temp.xlsx", 3)
    }
    fn get_output_file_name_advance(groupt_id: &str) -> String {
        format!("/tmp/advance-{groupt_id}.xlsx")
    }
}

#[test]
fn test_template_output() {
    let data = vec![
        MyData2::new("张三", "185xxxx2228", "网金部"),
        MyData2::new("李四", "185xxxx2229", "运管部"),
        MyData2::new("王二", "185xxxx2230", "网金部"),
    ];
    let resp = MyData2::write2xlsx_merge_only(
        &data,
        #[cfg(feature = "encrypt")]
        None,
    );
    println!("{resp:#?}");
}

struct MyData3 {
    pub name: String,
    pub tel: String,
    pub dep: String,
}

impl MyData3 {
    pub fn new(name: &str, tel: &str, dep: &str) -> Self {
        Self {
            name: name.into(),
            tel: tel.into(),
            dep: dep.into(),
        }
    }
}

impl XlsxGroupWrite for MyData3 {
    /// 行写入模式为高级写入模式，完全自定义
    const LINE_WRITER_MODEL: XlsxLineWriterModel = XlsxLineWriterModel::Advance;
    type ExtraArgType = ();
    /// 使用xlsx api 写入每行的数据
    fn line_writer_advance(
        &self,
        sheet: &mut Worksheet,
        index: u32,
    ) -> Option<XlsxLineAdvanceWriterResult> {
        xlsx_util::XlsxWriterTool::set_excel_cell_value_number(sheet, 1, index, index - 2);
        xlsx_util::XlsxWriterTool::set_excel_cell_value_str(sheet, 2, index, &self.name);
        xlsx_util::XlsxWriterTool::set_excel_cell_value_str(sheet, 3, index, &self.tel);
        xlsx_util::XlsxWriterTool::set_excel_cell_value_str(sheet, 4, index, &self.dep);
        None
    }
    fn get_template() -> XlsxInitTemplet {
        XlsxInitTemplet::new_advance("/home/feiy/Desktop/temp.xlsx", 4)
    }
    fn get_output_file_name_advance(groupt_id: &str) -> String {
        format!("/tmp/advance-{groupt_id}.xlsx")
    }
    fn add_custom_info_to_sheet(sheet: &mut Worksheet, group_id: &str) {
        sheet
            .get_cell_mut((&1, &2))
            .set_value_string(&format!("{group_id}，报表日期:2023年4月20日"));
    }
}

#[test]
fn test_advance_write() {
    let data = vec![
        MyData3::new("张三", "185xxxx2228", "网金部"),
        MyData3::new("李四", "185xxxx2229", "运管部"),
        MyData3::new("王二", "185xxxx2230", "网金部"),
    ];
    let resp = MyData3::write2xlsx_merge_only(
        &data,
        #[cfg(feature = "encrypt")]
        None,
    );
    println!("{resp:#?}");
}
